﻿using STTech.BytesIO.Core;
using STTech.BytesIO.Tcp;
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;

namespace TCP_Server
{
    public partial class Form1 : Form
    {
        private TcpServer server;
        public Form1()
        {
            InitializeComponent();

            //初始化server对象
            server = new TcpServer();
            //设置server的端口号
            server.Port = int.Parse(toolStrip_tbx_port.Text);

            //服务启动时触发的事件
            server.Started += Server_Started;
            //服务关闭时触发的事件
            server.Closed += Server_Closed;
            //客户端连接时触发的事件
            server.ClientConnected += Server_ClientConnected;
            //客户端断开连接时触发的事件
            server.ClientDisconnected += Server_ClientDisconnected;

            //接收客户端连接时的处理过程，加个服务端上限为只能容纳三个客户端
            server.ClientConnectionAcceptedHandle = (s, e) =>
            {
                if (server.Clients.Count() < 3)
                {
                    return true;
                }
                else
                {
                    Print($"服务器已满，关闭客户端[{e.ClientSocket.RemoteEndPoint}]的连接");
                    return false;
                }
            };
        }

        //客户端断开连接时触发的事件，对应的处理函数
        private void Server_ClientDisconnected(object sender, ClientDisconnectedEventArgs e)
        {
            Print($"客户端[{e.Client.Host}:{e.Client.Port}]断开连接");
        }

        //客户端连接时触发的事件，对应的处理函数
        private void Server_ClientConnected(object sender, ClientConnectedEventArgs e)
        {
            Print($"客户端[{e.Client.Host}:{e.Client.Port}]连接成功");
            //当客户端有数据返回时触发事件
            e.Client.OnDataReceived += Client_OnDataReceived;
            //和客户端建立心跳，如果客户端多长时间没回消息，就断开连接，3000单位是ms
            e.Client.UseHeartbeatTimeout(3000);
        }

        //处理客户端返回过来数据
        private void Client_OnDataReceived(object sender, STTech.BytesIO.Core.DataReceivedEventArgs e)
        {
            TcpClient tcpClient = (TcpClient)sender;
            Print($"来自客户端[{tcpClient.RemoteEndPoint}]的消息：{e.Data.EncodeToString("GBK")}");

            //收到某个客户端数据后，遍历server中客户端
            foreach(TcpClient client in server.Clients)
            {
                //找到非当前发数据的客户端
                if (client != tcpClient)
                {
                    //给这个客户端转发消息
                    client.SendAsync(e.Data);
                }
            }
        }

        //服务关闭时触发的事件，对应的处理函数
        private void Server_Closed(object sender, EventArgs e)
        {
            Print("停止监听");
        }

        //服务启动时触发的事件，对应的处理函数
        private void Server_Started(object sender, EventArgs e)
        {
            Print("开始监听");
        }
        private void Print(string msg)
        {
            //线程的修改直接更新到UI主线程是不被允许的，这里通过调用Form的Invoke方法跨线程访问控件
            this.Invoke(new Action(() =>
            {
                rtbx_log.AppendText($"[{DateTime.Now}] {msg}\r\n");
            }));

        }

        private void MenuItem_startListen_Click(object sender, EventArgs e)
        {
            //开始监听
            server.StartAsync();
        }

        
        private void MenuItem_closeListen_Click(object sender, EventArgs e)
        {
            //停止监听
            server.CloseAsync(); 
        }
    }
}
